/**
 *控制人沿障碍物走，有自动绕行,能在平台上跳
 */
 package kgame5.kgu {
import kgame5.k3d.core.obj3d.spacial.SpacialVO;

import flash.display.MovieClip;

public class PosiController {

  public static var G:int = -3;

  public function  PosiController() {
  }

  

 /**
   * 根据人物在地图的位置，根据地图障碍物信息，人物的方向和速度（方向为0就是无移动，因为方向为0）
   *其实，贴地形走也是这么回事
   *  @param role MovieClip2
   * @param BGBarData byte[][] 地图障碍物数组，1不可以走，0可以走
   * @param GRIDSIZE int
   * 
   * 注意一个重要的前提是上一个位置是稳定位置
   */
  public static function CalcPosi( md:SpacialVO, a2BarData:Array, CellSize:Number,md_shadow:SpacialVO=null,mc_testpane:MovieClip=null) {
  	
     //0，准备
		var A:Number=md.aabb.A;
		var B:Number=md.aabb.B;
		var H:Number=md.aabb.H;
  	
		//Step 1,计算并设置高度
		/*
      md.floorAltitude=calcFloorAltitude(md.v3d_p.x,md.v3d_p.y,md.v3d_p.z,A,B,H,a2BarData,CellSize);
     
      //影子高度也在这里
      //md.getShadow().v3d_p.y=md.floorAltitude+1;
      
     // _root.tf_h.text=md.v3d_p.y+" "+ md.floorAltitude;
      
      if(md.v3d_p.y>md.floorAltitude){
      	 md.v3d_v.y+= G;
    	 md.v3d_p.y+= md.v3d_v.y;
    	 
    	 if(md.v3d_p.y<=md.floorAltitude){
    	 	md.v3d_p.y=md.floorAltitude;
    	 	 md.v3d_v.y=0;
    	 	 T.p("到达目标");
    	 }
      }
     //*/
      //Step 2,速度分解，
      
      //0,打上移动有效的标志
      md.bXok=true;
      md.bZok=true;
     
     //计下自己当前的c,r
      var c:int=calcCol(md.v3d_p.x,CellSize);
       var r:int=calcRow(md.v3d_p.z,CellSize);
     
      //1,尝试加到指定位置
      md.v3d_p.x+=md.v3d_v.x;
      md.v3d_p.z+=md.v3d_v.z;
     
      //记下加到指定位置后的坐标
      var x:Number=md.v3d_p.x;
      var y:Number=md.v3d_p.y;
      var z:Number=md.v3d_p.z;
      
      var vx:Number=md.v3d_v.x;
       var vz:Number=md.v3d_v.z;
       
      
     
	 //2,记录跟周围8个格子碰撞的结果
      var b00:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r-1,c-1);
       var b01:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r-1,c);
        var b02:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r-1,c+1);
       
     var b10:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r,c-1);
      // var b11:Boolean=hitTest(x,y,z,A,B,H,a2BarData[r][c],CellSize,r,c);
        var b12:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r,c+1);
        
     var b20:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r+1,c-1);
       var b21:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r+1,c);
         var b22:Boolean=hitTest(x,y,z,A,B,H,a2BarData,CellSize,r+1,c+1);
        
         //*输出碰撞检测的情况
        // T.p(mc_testpane+"");
         if(mc_testpane!=null){
           mc_testpane.tf_0.text=b00;
        mc_testpane.tf_1.text=b01;
         mc_testpane.tf_2.text=b02;
         
          mc_testpane.tf_3.text=b10;
           mc_testpane.tf_5.text=b12;
           
             mc_testpane.tf_6.text=b20;
               mc_testpane.tf_7.text=b21;
          mc_testpane.tf_8.text=b22;
          
          mc_testpane.tf_4.text=c+" "+r;
          
          //
          mc_testpane.tf_9.text=
          	md.v3d_p.toString()+"\n"
          	+md.v3d_v.toString()+"\n";
         }
          //*/
          
      //3,分析具体情况设置bXok,bZok
     if(vx==0 && vz==0){
     	return;
     }else if(vx==0 && vz!=0){
     	if(vz>0){
     		if(b00 || b01 ||b02){//上面有一个撞上就不能走了
     			md.bZok=false;
     		}
     	}else if(vz<0){
     		if(b20 || b21 ||b22){//下面有一个撞上就不能走了
     			md.bZok=false;
     		}
     	}
     }else if(vx!=0 && vz==0){
     	if(vx>0){
     		if(b02 || b12 ||b22){//右面有一个撞上就不能走了
     			md.bXok=false;
     		}
     	}else if(vx<0){
     		if(b00 || b10 ||b20){//左面有一个撞上就不能走了
     			md.bXok=false;
     		}
     	}
     }else if(vx!=0 && vz!=0){
     	if(vx>0){
     		if(vz>0){
     			//----
     			if(b02){//有角
     				
     				 if((b01||b00) && b12==false){
     					md.bZok=false;
     				}else if(b01==false && (b12 ||b22)){
     					md.bXok=false;
     				}else {//两边都有或两边都没有则不能动
     					md.bZok=false;
     					md.bXok=false;
     				}
     			}else{//无角
     				if(b01||b00){
     					md.bZok=false;
     				}
     				if(b12||b22){
     					md.bXok=false;
     				}
     			}
     			//-----
     		}else if(vz<0){
     			//----
     			if(b22){//有角
     				
     				 if((b21||b20) && b12==false){
     					md.bZok=false;
     				}else if(b21==false && (b12||b02)){
     					md.bXok=false;
     				}else {//两边都有或两边都没有则不能动
     					md.bZok=false;
     					md.bXok=false;
     				}
     			}else{//无角
     				if(b21||b20){
     					md.bZok=false;
     				}
     				if(b12||b02){
     					md.bXok=false;
     				}
     			}
     			//-----
     		}
     	}else if(vx<0){
     		if(vz>0){
     			//----
     			if(b00){//有角
     				
     				 if((b01||b02) && b10==false){
     					md.bZok=false;
     				}else if(b01==false && (b10||b20)){
     					md.bXok=false;
     				}else {//两边都有或两边都没有则不能动
     					md.bZok=false;
     					md.bXok=false;
     				}
     			}else{//无角
     				if(b01||b02){
     					md.bZok=false;
     				}
     				if(b10||b20){
     					md.bXok=false;
     				}
     			}
     			//-----
     		}else if(vz<0){
     			//----
     			if(b20){//有角
     				
     				 if((b21||b22) && b10==false){
     					md.bZok=false;
     				}else if(b21==false && (b10||b00)){
     					md.bXok=false;
     				}else {//两边都有或两边都没有则不能动
     					md.bZok=false;
     					md.bXok=false;
     				}
     			}else{//无角
     				if(b21||b22){
     					md.bZok=false;
     				}
     				if(b10||b00){
     					md.bXok=false;
     				}
     			}
     			//-----
     		}
     	}
     }
     
      //Step 3 如果不能放到指定位置，则返回 
      if(md.bXok==false){
      	md.v3d_p.x-=md.v3d_v.x;
      }
      if(md.bZok==false){
      	md.v3d_p.z-=md.v3d_v.z;
      }
      
      //Step 4 设置影子位置
      if(md_shadow!=null){
      	md_shadow.v3d_p.x=md.v3d_p.x;
      	md_shadow.v3d_p.y=md.floorAltitude;
      	md_shadow.v3d_p.z=md.v3d_p.z;
      }
  }
 

 

  //！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
	public static function hitTest(x:Number,y:Number,z:Number,A:Number,B:Number,H:Number,
		a2BarData:Array,CellSize:Number,r:int,c:int):Boolean{
		
		//数组越界检查，很重要的
		if(r<0||r>a2BarData.length-1||c<0||c>a2BarData[0].length-1){
			return true;
		}
		
		var barHeight:Number=a2BarData[r][c];
		
		//高度的格子
		var h:Number=Math.floor(y/CellSize);//0,1,2,3
		
		var blockX:Number=calcX(c,CellSize);
		var blockZ:Number=calcZ(r,CellSize);
		
		var dx:Number=x-blockX;
		var dz:Number=z-blockZ;
		if(Math.abs(dx)<(A+CellSize)/2&&Math.abs(dz)<(B+CellSize)/2){
			if(barHeight>=(h+1)){
				return true;
			}
		}
		return false;
	}
	//检测自己底下的9个格子，这个是用来判断是否可以下落用的
	public static function hitTest9(x:Number,y:Number,z:Number,A:Number,B:Number,H:Number,
		a2BarData:Array,CellSize:Number):Boolean{
			var c:Number=calcCol(x,CellSize);
			var r:Number=calcRow(z,CellSize);
			if(
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r,c) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r-1,c) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r+1,c) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r,c-1) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r,c+1) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r-1,c-1) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r+1,c+1) ||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r-1,c+1)||
				hitTest(x,y,z,A,B,H,a2BarData,CellSize,r+1,c-1)
				){
					return true;
			}
			return false;
	}
	
	//计算一个位置的底部的高度
	public static function calcFloorAltitude(x:Number,y:Number,z:Number,A:Number,B:Number,H:Number,
		a2BarData:Array,CellSize:Number):Number{
			while(y>0){
				y-=CellSize;
				if(y<0){
					return 0;
				}
				if(hitTest9(x,y,z,A,B,H,a2BarData,CellSize)){
					var t:Number= (Math.floor(y/CellSize)+1)*CellSize;
					
					//T.p("下面有东西 y:"+y+" t:"+t);
					
					return t;
				}
			}
			return 0;
	}
	public static function calcX(col:int,CellSize:Number):Number{
		return col*CellSize+CellSize/2;
	}
	public static function calcZ(row:int,CellSize:Number):Number{
		return -(row*CellSize+CellSize/2);
	}
	public  static function calcCol(x:Number,CellSize:Number):int{
		return Math.floor(x/CellSize);
	}
	public static function calcRow(z:Number,CellSize:Number):int{
		return Math.floor(-z/CellSize);
	}
	
	//************************自动绕行****************************
	//在上方被阻挡的情况下自动绕行 origX是因为这里是尝试加到指定位置后的md.v3d_p,所以要用原始位置
	private static function autoDetourUP(md:SpacialVO,
					origX:Number,origY:Number,origZ:Number,
					CellSize:Number,
					b00:Boolean,b01:Boolean,b02:Boolean,
					b10:Boolean,b12:Boolean,
					b20:Boolean,b21:Boolean,b22:Boolean
					){
		var A:Number=md.aabb.A;
		var B:Number=md.aabb.B;
		var H:Number=md.aabb.H;
		
		
	}
}//end of Class 
 }